import ffmpeg
import io
import logging
from typing import Dict, Optional
from pathlib import Path
import tempfile
import os

logger = logging.getLogger(__name__)

class VideoService:
    SUPPORTED_FORMATS = ['mp4', 'avi', 'mkv', 'mov', 'wmv']
    
    RESOLUTION_MAP = {
        "1080p": (1920, 1080),
        "720p": (1280, 720),
        "480p": (854, 480),
        "360p": (640, 360)
    }
    
    @staticmethod
    async def convert_format(content: bytes, format: str) -> bytes:
        """转换视频格式"""
        if format not in VideoService.SUPPORTED_FORMATS:
            raise ValueError(f"不支持的格式: {format}")
            
        try:
            with tempfile.NamedTemporaryFile(delete=False) as temp_in:
                temp_in.write(content)
                temp_in_path = temp_in.name
                
            with tempfile.NamedTemporaryFile(suffix=f'.{format}', delete=False) as temp_out:
                temp_out_path = temp_out.name
            
            # 执行转换
            stream = ffmpeg.input(temp_in_path)
            stream = ffmpeg.output(
                stream,
                temp_out_path,
                acodec='aac',
                vcodec='libx264',
                preset='medium'
            )
            ffmpeg.run(stream, overwrite_output=True)
            
            # 读取结果
            with open(temp_out_path, 'rb') as f:
                result = f.read()
                
            return result
            
        except Exception as e:
            logger.error(f"视频转换失败: {str(e)}")
            raise
        finally:
            # 清理临时文件
            for path in [temp_in_path, temp_out_path]:
                try:
                    os.unlink(path)
                except:
                    pass

    @staticmethod
    async def compress_video(
        content: bytes,
        resolution: str,
        quality: int,
        bitrate: int
    ) -> bytes:
        """压缩视频"""
        try:
            with tempfile.NamedTemporaryFile(delete=False) as temp_in:
                temp_in.write(content)
                temp_in_path = temp_in.name
                
            with tempfile.NamedTemporaryFile(suffix='.mp4', delete=False) as temp_out:
                temp_out_path = temp_out.name
            
            # 构建转换命令
            stream = ffmpeg.input(temp_in_path)
            
            # 设置分辨率
            if resolution != "original" and resolution in VideoService.RESOLUTION_MAP:
                width, height = VideoService.RESOLUTION_MAP[resolution]
                stream = stream.filter('scale', width, height)
            
            # 设置编码参数
            output_args = {
                'vcodec': 'libx264',
                'acodec': 'aac',
                'preset': 'medium',
                'crf': str(int((100 - quality) * 0.51)),  # 将质量转换为 CRF (0-51)
                'b:v': f'{bitrate}k',
                'maxrate': f'{int(bitrate * 1.5)}k',  # 最大码率
                'bufsize': f'{bitrate * 2}k',  # 缓冲大小
                'movflags': 'faststart'  # 优化网络播放
            }
            
            stream = ffmpeg.output(stream, temp_out_path, **output_args)
            ffmpeg.run(stream, overwrite_output=True)
            
            # 读取结果
            with open(temp_out_path, 'rb') as f:
                result = f.read()
                
            return result
            
        except Exception as e:
            logger.error(f"视频压缩失败: {str(e)}")
            raise
        finally:
            # 清理临时文件
            for path in [temp_in_path, temp_out_path]:
                try:
                    os.unlink(path)
                except:
                    pass 